package com.world.rickcloudendpoint.service.tools;

import cn.hutool.core.lang.Assert;
import com.fasterxml.jackson.core.type.TypeReference;
import com.world.rickcloudendpoint.common.constant.GlobalConstants;
import com.world.rickcloudendpoint.common.utils.JsonUtils;
import com.world.rickcloudendpoint.models.params.common.PageBy;
import com.world.rickcloudendpoint.models.params.common.QueryDsl;
import com.world.rickcloudendpoint.models.params.common.QueryWhere;
import com.world.rickcloudendpoint.models.params.common.SortBy;
import org.apache.commons.lang3.StringUtils;
import org.bson.json.JsonParseException;
import org.springframework.data.domain.Sort;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @description: 分页工具
 * @author: jlsong
 * @date: 2022/01/22 23:35:29
 * @version: 1.0
 */
public class AggregateQueryTools {


    /**
     * 获取去排序规则
     *
     * @param sorts
     * @return
     */
    public static Sort getSorts(List<SortBy> sorts) {
        List<String> ascFields = new ArrayList<>();
        List<String> descFields = new ArrayList<>();
        for (SortBy params : sorts) {
            if (params.getBy().equals(GlobalConstants.Mongodb.SORT_ASC)) {
                ascFields.add(params.getField());
            } else if (params.getBy().equals(GlobalConstants.Mongodb.SORT_DESC)) {
                descFields.add(params.getField());
            }
        }
        Sort sort = null;
        if (ascFields.size() > 0) {
            sort = Sort.by(Sort.Direction.ASC, ascFields.toArray(new String[ascFields.size()]));
        }
        if (descFields.size() > 0) {
            sort = sort.by(Sort.Direction.DESC, descFields.toArray(new String[descFields.size()]));
        }
        return sort;
    }

    public static long getSkip(PageBy page) {
        Assert.notNull(page, "分页参数不能为空");
        long skip = page.getPageNum() <= 1 ? 0L : (page.getPageNum() - 1) * page.getPageSize() * 1L;
        return skip;
    }

    /**
     * 将字符串排序规则表达式转换成排序规则对象集合
     *
     * @param sorts
     * @return
     * @throws Exception
     */
    public static List<SortBy> parseSortsStr(String sorts) throws IllegalArgumentException {
        Collection<SortBy> collection = JsonUtils.string2Obj(sorts, new TypeReference<Collection<SortBy>>() {
        });
        if (collection != null && collection.size() > 0) {
            return collection.stream().collect(Collectors.toList());
        } else {
            SortBy sortBy = new SortBy();
            sortBy.setField("_id");
            sortBy.setBy("desc");
            List<SortBy> list = new ArrayList<>();
            list.add(sortBy);
            return list;
        }
    }

    public static PageBy parsePageOptions(Long offset, Integer size) {
        if (offset == null || size == null) {
            return null;
        }
        Assert.notNull(offset, "offset 不能为空");
        Assert.notNull(size, "size 不能为空");
        PageBy pageBy = new PageBy();
        if (size == -1) {
            pageBy.setPageNum(1);
        } else {
            Assert.state(size > 0, "size 必须为 -1 或正整数");
            Assert.state(offset > -1, "offset 不能为负整数");
            int num = (int) ((offset) / size);
            num = num <= 0 ? 1 : num;
            pageBy.setPageNum(num);
        }
        pageBy.setPageSize(size);
        return pageBy;
    }

    public static QueryWhere parseFilterCriteriaOptions(String exp, String dsl) throws JsonParseException {
        if (StringUtils.isEmpty(exp) || StringUtils.isEmpty(dsl)) {
            return null;
        }

        HashMap<String, QueryDsl> map = JsonUtils.string2Obj(dsl, new TypeReference<HashMap<String, QueryDsl>>() {
        });
        if (map != null && map.size() > 0) {
            QueryWhere where = new QueryWhere();
            where.setExp(exp);
            where.setDict(map);
            return where;
        }
        throw new JsonParseException("dsl表达式json格式不正确");
    }
}
